/*
 * Created by SharpDevelop.
 * User: phtrung
 * Date: 10/13/2009
 * Time: 4:17 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Drawing;
using System.Windows.Forms;
using popLib;
using System.Threading;
using System.IO;

namespace FileTransferSocket
{
	/// <summary>
	/// Description of Form1.
	/// </summary>
	public partial class Form1 : Form
	{
		Client clients;
		Server servers;
		string fromClientIP = "";
		
		public Form1()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			
			path.Text = Config.Singleton().SavePath;
			Global.Singleton().SavePath = path.Text = Path.IsPathRooted(path.Text) ? path.Text : FileLib.getFullPath(path.Text);
			
			port.Value  = NumberLib.getInt( Config.Singleton().ServerPort );
			ips.Text = Config.Singleton().ClientIP;

            Global.Singleton().ReceiveFileStatus += HandleReceiveFile;
            Global.Singleton().SendFileStatus += HandleSendFile;
			
			FormLib.dragAndDrop( this, DragSendFile  );
			FormLib.dragAndDrop( send, DragSendFile );
			FormLib.dragAndDrop( log, DragSendFile );
			
			
		}
        void HandleSendFile(string fileName, long fileSize, long transferedSize, Global.TranferStatus status)
        {
            HandleTransferFile(fileName, fileSize, transferedSize, status, true);
        }

        void HandleReceiveFile(string fileName, long fileSize, long transferedSize, Global.TranferStatus status)
        {
            HandleTransferFile(fileName, fileSize, transferedSize, status, false);
        }

        void HandleTransferFile(string fileName, long fileSize, long transferedSize, Global.TranferStatus status, bool isSending) {
            switch (status)
            {
                case Global.TranferStatus.Begin:
                    writeLog(string.Format( (isSending ? "Sending" : "Receiving") + " file: {0} ({1} kb)", fileName, fileSize / 1024), false, true);
                    break;

                case Global.TranferStatus.Transferring:
                    viewProgress(fileName, (int)((transferedSize * 100) / fileSize));
                    break;

                case Global.TranferStatus.End:
                    writeLog(" - Done.", true, false);
                    break;

                case Global.TranferStatus.Error:
                    writeLog(" - Fail.", true, false);
                    break;
            }
        }
		
		void ActionEvent(object sender, EventArgs e)
		{
			switch( ((Control)sender).Name ){
				case "connect": 
					clients = new Client( ips.Text, (int)port.Value );
					writeLog(string.Format("Client connect {0}:{1}", ips.Text, port.Value));
					
					clients.ServerConnected += delegate{ 
						writeLog("Client connect OK");
						
                        ThreadStart thread = delegate {
                            client.Enabled = server.Enabled = start.Enabled = connect.Enabled = false;
                            send.Enabled = true;
                        };
                        this.Invoke(thread);
					};
					
					clients.Connect();
					break;
				case "start": 
					servers = new Server((int)port.Value);
					writeLog("Server started - port: "+port.Value);
					client.Enabled = server.Enabled = start.Enabled = connect.Enabled = false;
					servers.ClientConnected += delegate(string ip){
						fromClientIP = ip;
						ThreadStart thread = delegate{ send.Enabled = true; };
                        this.Invoke( thread );
					};
					break;
				case "getpath": 
					ReturnSet rs = FormLib.folderBrowser();
					if( rs.Success ) Global.Singleton().SavePath = path.Text = rs.Result+"";
					break;				
				case "client":  
				case "server": 
					start.Enabled = server.Checked; 
					connect.Enabled = client.Checked;
					break;
				case "send": 
					ReturnSet rs1 = FormLib.openFile( "All file(*.*)|*.*", true );
					if( rs1.Success ){
						string[] files = (string[])rs1.Result;
						SendFile(files);
					}
					break;
			}
		}
		
		void DragSendFile( Control control, string[] files ){
			SendFile(files);
		}
		
		void SendFile( string[] files ){
			if( !send.Enabled ) return;
            if (files == null) return;

            Thread tmp = new Thread(executeSendFile);
            tmp.IsBackground = true;
            tmp.Start(files);
		}
		
		void executeSendFile(object obj){
            try
            {
                string[] files = (string[])obj;
                int counter = 0;
                foreach (string file in files)
                {
                	counter++;
                    if (client.Checked) clients.SendFile(file, counter, files.Length );
                    else servers.SendFile(file, fromClientIP, counter, files.Length);
                    Thread.Sleep(100);                    
                    viewProgress2( "", (int)((counter * 100) / files.Length) );
                }
            }
            catch (Exception ex) { FormLib.alert(ex); }
		}
		
		void writeLog( string msg ){
            writeLog( msg, true, true );
		}
		
		void writeLog( string msg, bool breakLine, bool showTime ){
			string previousMsg = (showTime ? DateTime.Now.ToString("HH:mm:ss") + "> " : "" ) + msg + (breakLine ? "\r\n" : "");
            ThreadStart thread = delegate
            {
                log.AppendText(previousMsg);
                log.Select(log.Text.Length, 0);
                log.ScrollToCaret();
            };
            this.Invoke(thread);
		}
		
		void viewProgress2( string text, int percent ){

            ThreadStart thread = delegate
            {
                progress2.Value = percent > 100 ? 100 : percent;
            };
            this.Invoke(thread);
		}
		
		void viewProgress( string text, int percent ){

            ThreadStart thread = delegate
            {
                progress.Value = percent > 100 ? 100 : percent;
            };
            this.Invoke(thread);

			
//			progress.CreateGraphics().DrawString( text + " - " + percent + "%", 
//			                                     new Font("Arial", (float)8.25, FontStyle.Regular), 
//			                                     Brushes.Black, 
//			                                     new Point(0,0));
			
		}
		
		
		void Form1FormClosing(object sender, FormClosingEventArgs e)
		{
			if( client.Checked && client != null ) clients.Shutdown();
			else if(servers != null) servers.Shutdown();
			Config.Singleton().ClientIP = client.Text;
			Config.Singleton().ServerPort = port.Value+"";
			Config.Singleton().SavePath = path.Text;
			Config.Singleton().saveData();
		}
	}
}
